#include "XenInfo.h"

bool XenInfo::displayInfoBar = true;

XenInfo::XenInfo(IDirect3DDevice9 *pIDirect3DDevice9)
{
	this->pIDirect3DDevice9 = pIDirect3DDevice9;
	Initialize();
}

void XenInfo::Initialize()
{
	InitMaxLevel();

	xenMemory = new XenMemory();

	D3DVIEWPORT9 viewport;
	pIDirect3DDevice9->GetViewport(&viewport);

	screenWidth = viewport.Width;
	screenHeight = viewport.Height;

	scaleX = screenWidth / 1280.0;
	scaleY = screenHeight / 1024.0;

	maxXp = -1;

	//Reset level calc timer...
	calcLevelSTime = 0;
	calcLevelXpHr = 0;
	calcLevelOldXp = 0;
	calcLevelMaxXpHr = 0;
	calcLevelTotalXpMade = 0;
	calcLevelSXp = 0;

	//Reset gold calc timer...
	calcGoldSTime = 0;
	calcGoldHr = 0;
	calcGoldOld = 0;
	calcGoldMaxHr = 0;
	calcGoldTotalMade = 0;
	calcGoldStart = 0;


	//Info Background
	D3DXCreateTextureFromFile(pIDirect3DDevice9, INFOBG_LOC, &infoBgTexture);
	D3DXCreateSprite(pIDirect3DDevice9, &infoBgSprite);

	//Info Fonts
	ZeroMemory(&fInfo, sizeof(D3DXFONT_DESC));
	strcpy(fInfo.FaceName, "Arial");
	fInfo.Height = -16 * scaleY;
	D3DXCreateFontIndirect(pIDirect3DDevice9, &fInfo,&statsInfoFont);
}

void XenInfo::Render()
{
	if (xenMemory->ReadPage() == 1) { //Main menu
		//Set maxXp initial value (-1 means not to display them)
		maxXp = -1;

		//Reset level calc timer...
		calcLevelSTime = 0;
		calcLevelXpHr = 0;
		calcLevelOldXp = 0;
		calcLevelMaxXpHr = 0;
		calcLevelTotalXpMade = 0;
		calcLevelSXp = 0;

		//Reset gold calc timer...
		calcGoldSTime = 0;
		calcGoldHr = 0;
		calcGoldOld = 0;
		calcGoldMaxHr = 0;
		calcGoldTotalMade = 0;
		calcGoldStart = 0;
	}

	if (xenMemory->ReadPage() == 0 && displayInfoBar) {

		maxXp = level[xenMemory->ReadLevel() + 1];

		//Current time
		time_t currentTime;
		time(&currentTime);

		//Information Background
		D3DSURFACE_DESC infoBgDesc;
		infoBgTexture->GetLevelDesc(0, &infoBgDesc);

		D3DXVECTOR2 infoBgScale;
		infoBgScale.x = 1 * scaleX;
		infoBgScale.y = 1 * scaleY;

		D3DXVECTOR2 infoBgPos;
		infoBgPos.x = 0;
		infoBgPos.y = 0;

		D3DXMATRIX infoBgMatrix;
		D3DXMatrixTransformation2D(&infoBgMatrix, NULL, 0.0, &infoBgScale, NULL, 0, &infoBgPos);

		infoBgSprite->Begin(D3DXSPRITE_ALPHABLEND);
		infoBgSprite->SetTransform(&infoBgMatrix);
		infoBgSprite->Draw(infoBgTexture, NULL, NULL, NULL, D3DCOLOR_ARGB(ConfigFile::InfoBarOpacity, 255, 255, 255));
		infoBgSprite->End();

		//Display Level calc information
		RECT statsInfoXpMadeRect1 = {infoBgPos.x + (5 * scaleX), infoBgPos.y, infoBgPos.x + (77 * scaleX), infoBgPos.y + infoBgDesc.Height * scaleY };
		RECT statsInfoXpMadeRect2 = {infoBgPos.x + (77 * scaleX), infoBgPos.y, infoBgPos.x + (135 * scaleX), infoBgPos.y + infoBgDesc.Height * scaleY };
		RECT statsInfoXpHrRect1 = {infoBgPos.x + (135 * scaleX), infoBgPos.y, infoBgPos.x + (200 * scaleX), infoBgPos.y + infoBgDesc.Height * scaleY };
		RECT statsInfoXpHrRect2 = {infoBgPos.x + (200 * scaleX), infoBgPos.y, infoBgPos.x + (270 * scaleX), infoBgPos.y + infoBgDesc.Height * scaleY };
		RECT statsInfoMaxXpHrRect1 = {infoBgPos.x + (270 * scaleX), infoBgPos.y, infoBgPos.x + (373 * scaleX), infoBgPos.y + infoBgDesc.Height * scaleY };
		RECT statsInfoMaxXpHrRect2 = {infoBgPos.x + (373 * scaleX), infoBgPos.y, infoBgPos.x + (435 * scaleX), infoBgPos.y + infoBgDesc.Height * scaleY };
		RECT statsInfoXpHrTnlRect1 = {infoBgPos.x + (435 * scaleX), infoBgPos.y, infoBgPos.x + (510 * scaleX), infoBgPos.y + infoBgDesc.Height * scaleY };
		RECT statsInfoXpHrTnlRect2 = {infoBgPos.x + (510 * scaleX), infoBgPos.y, infoBgPos.x + (575 * scaleX), infoBgPos.y + infoBgDesc.Height * scaleY };

		if (calcLevelSTime > 0) {

			int currentXp = xenMemory->ReadCurrentXP();

			int xpDiff = currentXp - calcLevelSXp;

			float timeDiff = difftime(currentTime, calcLevelSTime);

			float hrs = timeDiff / 3600.0;

			//XP/Hr
			if (hrs != 0 && (calcLevelOldXp != currentXp || ConfigFile::RealTimeInfo)) {
				calcLevelXpHr = xpDiff / hrs;

				//Max XP/Hr
				if (calcLevelMaxXpHr < calcLevelXpHr) {
					calcLevelMaxXpHr = calcLevelXpHr;
				}

				calcLevelOldXp = currentXp;
			}

			string calcLevelXpHrStr = Utils::ToString<int>(calcLevelXpHr);
			if (calcLevelXpHr >= 1000000) {
				calcLevelXpHrStr = Utils::ToString<float>(calcLevelXpHr/1000000.0) + "M";
			} else if (calcLevelXpHr >= 1000) {
				calcLevelXpHrStr = Utils::ToString<float>(calcLevelXpHr/1000.0) + "K";
			}

			string calcLevelMaxXpHrStr = Utils::ToString<int>(calcLevelMaxXpHr);
			if (calcLevelMaxXpHr >= 1000000) {
				calcLevelMaxXpHrStr = Utils::ToString<float>(calcLevelMaxXpHr/1000000.0) + "M";
			} else if (calcLevelMaxXpHr >= 1000) {
				calcLevelMaxXpHrStr = Utils::ToString<float>(calcLevelMaxXpHr/1000.0) + "K";
			}


			//XP Made
			string calcLevelTotalXpMadeStr = Utils::ToString<int>(calcLevelTotalXpMade + xpDiff);
			if ((calcLevelTotalXpMade + xpDiff) >= 1000000) {
				calcLevelTotalXpMadeStr = Utils::ToString<float>((calcLevelTotalXpMade + xpDiff)/1000000.0) + "M";
			} else if ((calcLevelTotalXpMade + xpDiff) >= 1000) {
				calcLevelTotalXpMadeStr = Utils::ToString<float>((calcLevelTotalXpMade + xpDiff)/1000.0) + "K";
			}
			
			//Time TNL
			string timeTnlStr = "N/A";
			if (maxXp > -1 && calcLevelXpHr != 0) {
				int xpTnl = maxXp - currentXp;
				float hoursTnl = xpTnl / (float)calcLevelXpHr;
				timeTnlStr = Utils::ToString<float>(hoursTnl) + " Hrs";
				if (hoursTnl < 1) {
					timeTnlStr = Utils::ToString<float>(hoursTnl * 60) + " Min";
				} else if (hoursTnl > 24) {
					timeTnlStr = Utils::ToString<float>(hoursTnl / 24) + " Days";
				}
			}

			statsInfoFont->DrawText(NULL, "XP Made: ", -1, &statsInfoXpMadeRect1, DT_VCENTER, D3DCOLOR_ARGB(255, 255, 192, 0));
			statsInfoFont->DrawText(NULL, calcLevelTotalXpMadeStr.c_str(), -1, &statsInfoXpMadeRect2, DT_VCENTER, D3DCOLOR_RGBA(255, 255, 255, 255));
			statsInfoFont->DrawText(NULL, "XP/Hour: ", -1, &statsInfoXpHrRect1, DT_VCENTER, D3DCOLOR_ARGB(255, 255, 192, 0));
			statsInfoFont->DrawText(NULL, calcLevelXpHrStr.c_str(), -1, &statsInfoXpHrRect2, DT_VCENTER, D3DCOLOR_RGBA(255, 255, 255, 255));
			statsInfoFont->DrawText(NULL, "Most XP/Hour: ", -1, &statsInfoMaxXpHrRect1, DT_VCENTER, D3DCOLOR_ARGB(255, 255, 192, 0));
			statsInfoFont->DrawText(NULL, calcLevelMaxXpHrStr.c_str(), -1, &statsInfoMaxXpHrRect2, DT_VCENTER, D3DCOLOR_RGBA(255, 255, 255, 255));
			statsInfoFont->DrawText(NULL, "Time/TNL: ", -1, &statsInfoXpHrTnlRect1, DT_VCENTER, D3DCOLOR_ARGB(255, 255, 192, 0));
			statsInfoFont->DrawText(NULL, timeTnlStr.c_str(), -1, &statsInfoXpHrTnlRect2, DT_VCENTER, D3DCOLOR_RGBA(255, 255, 255, 255));
		} else { //calcLevelSTime hasn't started yet
			statsInfoFont->DrawText(NULL, "XP Made: ", -1, &statsInfoXpMadeRect1, DT_VCENTER, D3DCOLOR_ARGB(255, 255, 192, 0));
			statsInfoFont->DrawText(NULL, "N/A", -1, &statsInfoXpMadeRect2, DT_VCENTER, D3DCOLOR_RGBA(255, 255, 255, 255));
			statsInfoFont->DrawText(NULL, "XP/Hour: ", -1, &statsInfoXpHrRect1, DT_VCENTER, D3DCOLOR_ARGB(255, 255, 192, 0));
			statsInfoFont->DrawText(NULL, "N/A", -1, &statsInfoXpHrRect2, DT_VCENTER, D3DCOLOR_RGBA(255, 255, 255, 255));
			statsInfoFont->DrawText(NULL, "Most XP/Hour: ", -1, &statsInfoMaxXpHrRect1, DT_VCENTER, D3DCOLOR_ARGB(255, 255, 192, 0));
			statsInfoFont->DrawText(NULL, "N/A", -1, &statsInfoMaxXpHrRect2, DT_VCENTER, D3DCOLOR_RGBA(255, 255, 255, 255));
			statsInfoFont->DrawText(NULL, "Time/TNL: ", -1, &statsInfoXpHrTnlRect1, DT_VCENTER, D3DCOLOR_ARGB(255, 255, 192, 0));
			statsInfoFont->DrawText(NULL, "N/A", -1, &statsInfoXpHrTnlRect2, DT_VCENTER, D3DCOLOR_RGBA(255, 255, 255, 255));
		}

		//Seperator
		RECT statsInfoSeperator1 = {infoBgPos.x + (575 * scaleX), infoBgPos.y, infoBgPos.x + (578 * scaleX), infoBgPos.y + infoBgDesc.Height * scaleY };
		statsInfoFont->DrawText(NULL, " | ", -1, &statsInfoSeperator1, DT_VCENTER | DT_CENTER, D3DCOLOR_RGBA(255, 255, 255, 255));

		//Display money info
		RECT statsInfoMoney1 = {infoBgPos.x + (585 * scaleX), infoBgPos.y, infoBgPos.x + (625 * scaleX), infoBgPos.y + infoBgDesc.Height * scaleY };
		RECT statsInfoMoney2 = {infoBgPos.x + (625 * scaleX), infoBgPos.y, infoBgPos.x + (740 * scaleX), infoBgPos.y + infoBgDesc.Height * scaleY };
		RECT statsInfoMoneyHr1 = {infoBgPos.x + (740 * scaleX), infoBgPos.y, infoBgPos.x + (800 * scaleX), infoBgPos.y + infoBgDesc.Height * scaleY };
		RECT statsInfoMoneyHr2 = {infoBgPos.x + (800 * scaleX), infoBgPos.y, infoBgPos.x + (915 * scaleX), infoBgPos.y + infoBgDesc.Height * scaleY };

		//Current gold
		int money = xenMemory->ReadMoney();
		int platinum = money / 1000000;
		int gold = (money - (platinum * 1000000)) / 10000;
		int silver = (money - (platinum * 1000000) - (gold * 10000)) / 100;
		int copper = (money - (platinum * 1000000) - (gold * 10000) - (silver * 100));
		string moneyStr = Utils::ToString<int>(platinum) + "p " + Utils::ToString<int>(gold) + "g " + Utils::ToString<int>(silver) + "s " + Utils::ToString<int>(copper) + "c ";
		

		//Gold per hour
		string moneyHrStr = "N/A";

		if (calcGoldSTime > 0) {
			int currentGold = xenMemory->ReadMoney();

			int goldDiff = currentGold - calcGoldStart;

			float timeDiff = difftime(currentTime, calcGoldSTime);

			float hrs = timeDiff / 3600;

			if (hrs != 0 && (calcGoldOld != currentGold || ConfigFile::RealTimeInfo)) {
				calcGoldHr = goldDiff / hrs;

				//Max XP/Hr
				if (calcGoldMaxHr < calcGoldHr) {
					calcGoldMaxHr = calcGoldHr;
				}

				calcGoldOld = currentGold;
			}

			int moneyHr = calcGoldHr;
			int platinumHr = moneyHr / 1000000;
			int goldHr = (moneyHr - (platinumHr * 1000000)) / 10000;
			int silverHr = (moneyHr - (platinumHr * 1000000) - (goldHr * 10000)) / 100;
			int copperHr = (moneyHr - (platinumHr * 1000000) - (goldHr * 10000) - (silverHr * 100));
			moneyHrStr = Utils::ToString<int>(platinumHr) + "p " + Utils::ToString<int>(goldHr) + "g " + Utils::ToString<int>(silverHr) + "s " + Utils::ToString<int>(copperHr) + "c ";
		}
		statsInfoFont->DrawText(NULL, "Gold:", -1, &statsInfoMoney1, DT_VCENTER, D3DCOLOR_ARGB(255, 255, 192, 0));
		statsInfoFont->DrawText(NULL, moneyStr.c_str(), -1, &statsInfoMoney2, DT_VCENTER, D3DCOLOR_RGBA(255, 255, 255, 255));
		statsInfoFont->DrawText(NULL, "Gold/Hr:", -1, &statsInfoMoneyHr1, DT_VCENTER, D3DCOLOR_ARGB(255, 255, 192, 0));
		statsInfoFont->DrawText(NULL, moneyHrStr.c_str(), -1, &statsInfoMoneyHr2, DT_VCENTER, D3DCOLOR_RGBA(255, 255, 255, 255));


		//Seperator
		RECT statsInfoSeperator2 = {infoBgPos.x + (915 * scaleX), infoBgPos.y, infoBgPos.x + (918 * scaleX), infoBgPos.y + infoBgDesc.Height * scaleY };
		statsInfoFont->DrawText(NULL, " | ", -1, &statsInfoSeperator2, DT_VCENTER | DT_CENTER, D3DCOLOR_RGBA(255, 255, 255, 255));

		//Display current light levels
		RECT statsInfoTOD1 = {infoBgPos.x + (925 * scaleX), infoBgPos.y, infoBgPos.x + (963 * scaleX), infoBgPos.y + infoBgDesc.Height * scaleY };
		RECT statsInfoTOD2 = {infoBgPos.x + (963 * scaleX), infoBgPos.y, infoBgPos.x + (1000 * scaleX), infoBgPos.y + infoBgDesc.Height * scaleY };

		statsInfoFont->DrawText(NULL, "Light:", -1, &statsInfoTOD1, DT_VCENTER, D3DCOLOR_ARGB(255, 255, 192, 0));
		statsInfoFont->DrawText(NULL, Utils::ToString<int>(xenMemory->ReadCurrentLight()).c_str(), -1, &statsInfoTOD2, DT_VCENTER, D3DCOLOR_RGBA(255, 255, 255, 255));

		//Display current X and Y locations
		RECT statsInfoX1 = {infoBgPos.x + (998 * scaleX), infoBgPos.y, infoBgPos.x + (1016 * scaleX), infoBgPos.y + infoBgDesc.Height * scaleY };
		RECT statsInfoX2 = {infoBgPos.x + (1016 * scaleX), infoBgPos.y, infoBgPos.x + (1056 * scaleX), infoBgPos.y + infoBgDesc.Height * scaleY };
		RECT statsInfoY1 = {infoBgPos.x + (1056 * scaleX), infoBgPos.y, infoBgPos.x + (1074 * scaleX), infoBgPos.y + infoBgDesc.Height * scaleY };
		RECT statsInfoY2 = {infoBgPos.x + (1074 * scaleX), infoBgPos.y, infoBgPos.x + (1128 * scaleX), infoBgPos.y + infoBgDesc.Height * scaleY };

		statsInfoFont->DrawText(NULL, "X:", -1, &statsInfoX1, DT_VCENTER, D3DCOLOR_ARGB(255, 255, 192, 0));
		statsInfoFont->DrawText(NULL, Utils::ToString<int>(xenMemory->ReadLocX()).c_str(), -1, &statsInfoX2, DT_VCENTER, D3DCOLOR_RGBA(255, 255, 255, 255));
		statsInfoFont->DrawText(NULL, "Y:", -1, &statsInfoY1, DT_VCENTER, D3DCOLOR_ARGB(255, 255, 192, 0));
		statsInfoFont->DrawText(NULL, Utils::ToString<int>(xenMemory->ReadLocY()).c_str(), -1, &statsInfoY2, DT_VCENTER, D3DCOLOR_RGBA(255, 255, 255, 255));



		//Display FPS/Server/Current Time (Positioned from right edge of screen)
		RECT statsInfoFpsRect1 = {screenWidth - (175 * scaleX), infoBgPos.y, screenWidth - (125 * scaleX), infoBgPos.y + infoBgDesc.Height * scaleY };
		RECT statsInfoFpsRect2 = {screenWidth - (125 * scaleX), infoBgPos.y, screenWidth - (100 * scaleX), infoBgPos.y + infoBgDesc.Height * scaleY };
		RECT statsInfoServerRect1 = {screenWidth - (100 * scaleX), infoBgPos.y, screenWidth - 75 * scaleX, infoBgPos.y + infoBgDesc.Height * scaleY };
		RECT statsInfoTimeRect1 = {screenWidth - (70 * scaleX), infoBgPos.y, screenWidth - (10 * scaleX), infoBgPos.y + infoBgDesc.Height * scaleY };
		
		//Server
		/*string serverStr = "";
		switch (xenMemory.ReadServer()) {
			case 0: //X1
				serverStr = "X1";
				break;

			case 1: //X2
				serverStr = "X2";
				break;

			case 2: //DS
				serverStr = "DS";
				break;

			case 3: //X3
				serverStr = "X3";
				break;

			case 4: //X3 DS
				serverStr = "DS";
				break;
		}*/

		//Time
		tm localTime = *(localtime(&currentTime));
		int hour = 0;
		string amPm = "";
		if (localTime.tm_hour == 0) {
			hour = 12;
			amPm = "AM";
		} else if (localTime.tm_hour > 0 && localTime.tm_hour < 12) {
			hour = localTime.tm_hour;
			amPm = "AM";
		}else if (localTime.tm_hour == 12) {
			hour = localTime.tm_hour;
			amPm = "PM";
		} else if (localTime.tm_hour > 12) {
			hour = localTime.tm_hour - 12;
			amPm = "PM";
		}
		string minStr = Utils::ToString<int>(localTime.tm_min);
		if (localTime.tm_min < 10)
			minStr = "0" + minStr;

		string localTimeStr = Utils::ToString<int>(hour) + ":" + minStr + " " + amPm;

		statsInfoFont->DrawText(NULL, "FPS: ", -1, &statsInfoFpsRect1, DT_VCENTER | DT_RIGHT, D3DCOLOR_RGBA(255, 192, 0, 255));
		statsInfoFont->DrawText(NULL, Utils::ToString<int>(xenMemory->ReadFPS()).c_str(), -1, &statsInfoFpsRect2, DT_VCENTER, D3DCOLOR_RGBA(255, 255, 255, 255));
		//statsInfoFont->DrawText(NULL, serverStr.c_str(), -1, &statsInfoServerRect1, DT_VCENTER |  DT_RIGHT, D3DCOLOR_RGBA(0, 244, 0, 255));
		statsInfoFont->DrawText(NULL, localTimeStr.c_str(), -1, &statsInfoTimeRect1, DT_VCENTER | DT_RIGHT, D3DCOLOR_RGBA(255, 255, 255, 255));
	}
}

void XenInfo::ProcessInput()
{
	if (xenMemory->ReadPage() == 0) {
		static bool keyReleased = true;

		if (Input::KeysDown(ConfigFile::InfoBarDisplay)) {
			if(keyReleased) {
				if (displayInfoBar) {
					displayInfoBar = false;
				} else { 
					displayInfoBar = true;	
				}
			}
			keyReleased = false;
		} else {
			keyReleased = true;
		}

		if (Input::KeysDown(ConfigFile::LevelCalcInput))
		{
			time(&calcLevelSTime);
			if (calcLevelSXp != 0) {
				calcLevelTotalXpMade += xenMemory->ReadCurrentXP() - calcLevelSXp;
			}
			calcLevelSXp = xenMemory->ReadCurrentXP();
			calcLevelXpHr = 0;
			calcLevelOldXp = 0;
			calcLevelMaxXpHr = 0;			
		}

		if (Input::KeysDown(ConfigFile::GoldCalcInput))
		{
			time(&calcGoldSTime);
			if (calcGoldStart != 0) {
				calcGoldTotalMade += xenMemory->ReadMoney() - calcGoldStart;
			}
			calcGoldStart = xenMemory->ReadMoney();
			calcGoldHr = 0;
			calcGoldOld = 0;
			calcGoldMaxHr = 0;			
		}			
	}
}

void XenInfo::InitMaxLevel()
{
	level[0] = -1; //offset no level 0
	level[1] = -1;
	level[2] = 200;
	level[3] = 1000;
	level[4] = 2000;
	level[5] = 4000;
	level[6] = 7000;
	level[7] = 12000;
	level[8] = 22000;
	level[9] = 35000;
	level[10] = 50000;
	level[11] = 70000;
	level[12] = 100000;
	level[13] = 150000;
	level[14] = 250000;
	level[15] = 450000;
	level[16] = 750000;
	level[17] = 1250000;
	level[18] = 1750000;
	level[19] = 2250000;
	level[20] = 2750000;
	level[21] = 3500000;
	level[22] = 4250000;
	level[23] = 5000000;
	level[24] = 6000000;
	level[25] = 7000000;
	level[26] = 8000000;
	level[27] = 10000000;
	level[28] = 12000000;
	level[29] = 14500000;
	level[30] = 17000000;
	level[31] = 19500000;
	level[32] = 22000000;
	level[33] = 25000000;
	level[34] = 28000000;
	level[35] = 32000000;
	level[36] = 37000000;
	level[37] = 42000000;
	level[38] = 48000000;
	level[39] = 54000000;
	level[40] = 60000000;
	level[41] = 67000000;
	level[42] = 74000000;
	level[43] = 82000000;
	level[44] = 90000000;
	level[45] = 98000000;
	level[46] = 108000000;
	level[47] = 118000000;
	level[48] = 130000000;
	level[49] = 150000000;
	level[50] = 160000000;
	level[51] = 180000000;
	level[52] = 200000000;
	level[53] = 230000000;
	level[54] = 260000000;
	level[55] = 290000000;
	level[56] = 320000000;
	level[57] = 350000000;
	level[58] = 400000000;
	level[59] = 450000000;
	level[60] = 500000000;
	level[61] = 600000000;
	level[62] = 700000000;
	level[63] = 800000000;
	level[64] = 1000000000;
	level[65] = 1200000000;
	level[66] = 1400000000;
	level[67] = 1600000000;
	level[68] = 1800000000;
	level[69] = 2000000000;
	level[70] = 2500000000;
	level[71] = 2750000000;
	level[72] = 3000000000;
	level[73] = 3250000000;
	level[74] = 3500000000;
	level[75] = 3750000000;
	level[76] = 4000000000;
	level[77] = 4250000000;
	level[78] = 4260000000;
	level[79] = 4270000000;
}


void XenInfo::Release()
{
	infoBgTexture->Release();
	infoBgSprite->Release();
	statsInfoFont->Release();

	delete(xenMemory);
}